<template>
    <div>
        <h1>Vuex模块化</h1>
        <!-- 
            模块化的vuex使用语法一共有8个，分为属性调用类型的4个、函数映射类型的4个。
            操作vuex可以在视图中直接进行（不要写this），也可以在js中执行。

            1. 属性类型形如this.$store.xxxx.yyy.zzz
            2. 函数映射类型需要在使用之前先导入相关映射函数
         -->
        <hr />
        <div>
            模块化之前：count的直接获取：{{ $store.state.count }}
            模块化之后：gender的直接获取：{{ $store.state.users.gender }}
        </div>
        <div>当然也可以点击获取：<button @click="getCount">点击获取</button></div>
        <div>通过属性映射来获取的gendert是：{{ gender }}</div>

        <hr />

        <div>
            <h5>mutaions中方法的调用</h5>
            <div><button @click="add">通过属性形式进行调用</button></div>
        </div>

        <hr/>
        <div>
            <h5>actions中方法的调用</h5>
            <div>当前用户名：{{$store.state.username}}</div>
            <div><button @click="setAsync">通过属性形式进行调用</button></div>
        </div>

        <hr/>
        <div>
            <h5>getters中方法的调用</h5>
            <div>
                <button @click="ageIsAdult">直接通过属性获取</button>
            </div>
        </div>
    </div>
</template>

<script>
// 导入映射函数
import { mapState, mapMutations, mapActions, mapGetters } from "vuex";
// 映射类型函数分类：
// 一类：mapState，mapGetters，需要在计算属性中展开，然后自动映射成当前vue实例的属性(使用的方式与自身的props差不多，切记不能直接修改)
// 二类：mapMutations，mapActions，需要在方法中展开，然后自动映射成当前vue实例的方法
export default {
    methods: {
        // 映射mapMutations
        ...mapMutations(["addCount", "setAge"]),
        // 映射mapActions
        ...mapActions(["setUsername"]),
        getCount() {
            // 属性类型调用形式（以前）
            // console.log(this.$store.state.count);
            // 属性类型调用形式（现在）
            console.log(this.$store.state.users.gender);
            // 获取经过映射的属性（以前）
            // console.log(this.count);
            // console.log(this.age);
            // 获取经过映射的属性（现在）
            console.log(this.gender);
            console.log(this.age);
        },
        // 事件处理程序
        add() {
            // 通过属性形式进行调用“commit”
            // 参数1：具体的mutations中的函数名
            // 参数2：对应的方法的第二个形参数据（可选）
            // this.$store.commit("addCount");
            // this.$store.commit("setAge", 88);
            // 通过映射函数来使用（原本的第二个参数会被作为函数的实参）
            this.addCount();
            this.setAge(77);
        },
        // setAsync，异步设置用户名
        setAsync(){
            // 通过属性形式进行调用“dispatch”
            // 参数1：具体的actions中的函数名
            // 参数2：对应的方法的第二个形参数据（可选）
            // this.$store.dispatch("setUsername","张三")
            // 通过函数映射来使用（原本的第二个参数会被作为函数的实参）
            this.setUsername("李狗蛋")
        },
        // getters
        // 注意点：getters在声明的时候其形式虽然是函数，但是在实际调用的时候其是属性，因此不能加“()”，更不会涉及传递参数的问题（与state非常像）
        ageIsAdult(){
            // 通过属性的形式调用“getters”
            console.log(this.$store.getters.isAdult);
            // 通过映射函数进行调用
            console.log(this.isAdult);
        }
    },
    // 计算属性
    computed: {
        // 需要告诉其我们需要哪些数据（以前）
        // ...mapState(["count", "age"]),
        // 需要告诉其我们需要哪些数据（现在）
        ...mapState("users",["gender", "age"]),
        // 映射mapGetters
        ...mapGetters(["isAdult"])
    },
};
</script>
